

PM_FUNC_NORM_ATTRIB MenuCreate( const String:szTitle[], any:... )
{
	new String:szMenuTitle[128];
	vformat( szMenuTitle, charsmax(szMenuTitle), szTitle, 2 );

	pokemod_funcstart_debug( "MenuCreate '%s'", szMenuTitle );
	pokemod_funcend_debug( "MenuCreate" );

	return menu_create( szMenuTitle, "MenuHandler" );
}
PM_FUNC_NORM_ATTRIB MenuAddItem( const Int:iMenu, const String:szData[], const String:szText[], any:... )
{
	if ( iMenu == -1 )
		return 0;

	new String:szItem[128];
	vformat( szItem, charsmax(szItem), szText, 4 );

	pokemod_funcstart_debug( "MenuAddItem '%s' '%s'", szItem, szData );
	pokemod_funcend_debug( "MenuAddItem" );

	return menu_additem( iMenu, szItem, szData );
}
PM_FUNC_NORM_ATTRIB MenuAddText( const Int:iMenu, const String:szText[], any:... )
{
	if ( iMenu == -1 )
		return 0;

	new String:szItem[128];
	vformat( szItem, charsmax(szItem), szText, 3 );

	pokemod_funcstart_debug( "MenuAddText '%s'", szItem );
	pokemod_funcend_debug( "MenuAddText" );

	return menu_addtext( iMenu, szItem, 0 );
}
PM_FUNC_NORM_ATTRIB MenuExit( const Int:iPlayer, const Int:iMenu, const bool:bExitOption, const String:szExitName[] = "Exit" )
{
	if ( iMenu == -1 )
		return;

	pokemod_funcstart_debug( "MenuExit '%d'", bExitOption );

	if ( bExitOption && !PlayerGetInfo( iPlayer, PINFO_BOT ) )
	{
		if ( menu_items( iMenu ) < 10 )
		{
			menu_setprop( iMenu, MPROP_PERPAGE, 0 );
			MenuAddItem( iMenu, MENU_FAKE_EXIT, szExitName );
		}
		else
		{
			menu_setprop( iMenu, MPROP_EXIT, MEXIT_ALL );
			menu_setprop( iMenu, MPROP_EXITNAME, szExitName );
		}
	}
	else
	{
		menu_setprop( iMenu, MPROP_EXIT, MEXIT_NEVER );
	}

	pokemod_funcend_debug( "MenuExit" );
}

PM_FUNC_NORM_ATTRIB MenuDisplay( Int:iPlayer, Int:iMenu, PM_MENUS:iMenuType )
{
	if ( !is_user_connected( iPlayer ) )
	{
		menu_destroy( iMenu );
		return;
	}

	pokemod_funcstart_debug( "MenuDisplay menu type %d", iMenuType );

	switch( iMenuType )
	{
		case MENU_SKILLS, MENU_USE_ITEM, MENU_TRADE, MENU_TRADE_SUB, MENU_COMMAND, MENU_ADMINCOMMAND:
		{
			if ( iMenuType == g_iPlayerMenuType[ iPlayer ] )
			{
				g_iPlayerMenuType[ iPlayer ] = MENU_NONE;
				show_menu( iPlayer, 0, "^n", 1 );
			}
		}
	}

/*
	new Int:iMenuID, Int:iKeys;
	get_user_menu( iPlayer, iMenuID, iKeys );
	if ( g_iState == PM_DISABLED || ( iMenuID && iKeys ) )
*/
	new Int:iOldMenu, Int:iNewMenu;
	player_menu_info( iPlayer, iOldMenu, iNewMenu );
	if ( g_iState == PM_DISABLED || ( iOldMenu > 0 || iNewMenu > -1 ) )
	{
		new Array:iPlayerMenus = g_iPlayerMenus[ iPlayer ];
		if ( iPlayerMenus == Invalid_Array )
			iPlayerMenus = g_iPlayerMenus[ iPlayer ] = ArrayCreate( 1, 1 );

		ArrayPushCell( iPlayerMenus, iMenu );
		ArrayPushCell( iPlayerMenus, iMenuType );

		pokemod_funcend_debug( "MenuDisplay player has menu already" );

		return;
	}

	menu_cancel( iPlayer );
	g_iPlayerMenuType[ iPlayer ] = iMenuType;

	if ( PlayerGetInfo( iPlayer, PINFO_BOT ) )
	{
		if ( PlayerGetInfo( iPlayer, PINFO_BOT_ACTIONS ) )
		{
			PlayerAddInfo( iPlayer, PINFO_BOT_ACTIONS, -1 );

			new Int:iItem = random( menu_items( iMenu ) );

			new Int:iParm[ 3 ];
			iParm[ 0 ] = iPlayer;
			iParm[ 1 ] = iMenu;
			iParm[ 2 ] = iItem;
			set_task( random_float( 1.0, 15.0 ), "MenuBotSelect", 0, iParm, sizeof( iParm ) );
		}
		else
		{
			menu_destroy( iMenu );
		}
	}
	else
	{
		menu_display( iPlayer, iMenu );
	}

	pokemod_funcend_debug( "MenuDisplay successful" );
}

PM_FUNC_PUBLIC_ATTRIB MenuBotSelect( Int:iParm[ 3 ] )
{
	pokemod_funcstart_debug( "MenuBotSelect" );

	new Int:iPlayer = iParm[ 0 ];
	new Int:iMenu = iParm[ 1 ];
	new Int:iItem = iParm[ 2 ];

	if ( PlayerGetInfo( iPlayer, PINFO_CONNECT ) && PlayerGetInfo( iPlayer, PINFO_BOT ) )
		MenuHandler( iPlayer, iMenu, iItem );
	else
		menu_destroy( iMenu );

	pokemod_funcend_debug( "MenuBotSelect" );
}

PM_FUNC_NORM_ATTRIB MenuClose( Int:iPlayer, PM_MENUS:iClosedMenu )
{
	if ( !is_user_connected( iPlayer ) )
		return;

	pokemod_funcstart_debug( "MenuClose %d", iClosedMenu );

	switch( iClosedMenu )
	{
		case MENU_NONE, MENU_MAIN, MENU_CHANGE_POKE, MENU_USE_ITEM:
		{
			new Array:iPlayerMenus = g_iPlayerMenus[ iPlayer ];
			if ( iPlayerMenus == Invalid_Array )
			{
				g_iPlayerMenuType[ iPlayer ] = MENU_NONE;

				pokemod_funcend_debug( "MenuClose" );

				return;
			}

			new Int:iMenu = ArrayGetCell( iPlayerMenus, 0 );
			new PM_MENUS:iMenuType = PM_MENUS:ArrayGetCell( iPlayerMenus, 1 );

			new Int:iMenusLeft = ( ArraySize( iPlayerMenus ) / 2 ) - 1;

			if ( iMenusLeft >= 1 )
			{
				ArrayDeleteItem( iPlayerMenus, 0 );
				ArrayDeleteItem( iPlayerMenus, 0 );
			}
			else
			{
				ArrayDestroy( g_iPlayerMenus[ iPlayer ] );
			}

			menu_cancel( iPlayer );
			g_iPlayerMenuType[ iPlayer ] = iMenuType;
			menu_display( iPlayer, iMenu );
		}
		case MENU_SKILLS:
		{
			PlayerSetInfo( iPlayer, PINFO_ACTIVE_SKILLNUM, 0 );
		}
		case MENU_PC_ADVANCED:
		{
			MenuPC( iPlayer );
		}
		case MENU_TRADE_SUB:
		{
			TradeMenu( iPlayer );
		}
		case MENU_ADMINCOMMAND:
		{
			AdminMenu( iPlayer );
		}
		default:
		{
			if ( g_iPlayerMenus[ iPlayer ] == Invalid_Array && !PlayerGetInfo( iPlayer, PINFO_BOT ) )
				MenuMain( iPlayer, .bForceDisplay = true );
			else
				MenuClose( iPlayer, MENU_NONE );
		}
	}

	pokemod_funcend_debug( "MenuClose" );
}

PM_FUNC_PUBLIC_ATTRIB MenuDelayExit( Int:iParm[2] )
{
	pokemod_funcstart_debug( "MenuDelayExit" );

	MenuClose( iParm[0], PM_MENUS:iParm[1] );

	pokemod_funcend_debug( "MenuDelayExit" );
}

PM_FUNC_PUBLIC_ATTRIB MenuHandler( Int:iPlayer, Int:iMenu, Int:iMenuItem )
{
	pokemod_funcstart_debug( "MenuHandler" );

	new PM_MENUS:iMenuType = g_iPlayerMenuType[ iPlayer ];

	if ( iMenuItem == MENU_EXIT )
	{
		switch( iMenuType )
		{
			//Things we don't want to be able to close
			case MENU_SETUP, MENU_EVOLVE, MENU_LEARN_SKILL, MENU_USE_ITEM:
			{
				//So we just add it to their menu list
				new Array:iPlayerMenus = g_iPlayerMenus[ iPlayer ];
				if ( iPlayerMenus == Invalid_Array )
					iPlayerMenus = g_iPlayerMenus[ iPlayer ] = ArrayCreate( 1, 1 );

				ArrayPushCell( iPlayerMenus, iMenu );
				ArrayPushCell( iPlayerMenus, iMenuType );
			}
			default:
			{
				menu_destroy(iMenu);

				//Delay close because there is a rare bug with MENU_EXIT and menu_display
				//It might be from players disconnecting, but this will fix that.
				new Int:iParm[2];
				iParm[0] = iPlayer;
				iParm[1] = _:iMenuType;
				set_task( 0.1, "MenuDelayExit", _, iParm, sizeof iParm );
			}
		}

		pokemod_funcend_debug( "MenuHandler MENU_EXIT" );

		return PLUGIN_HANDLED;
	}

	new String:szData[128], String:szName[64];
	new Int:iAccess, Int:iCallBack;
	menu_item_getinfo( iMenu, iMenuItem, iAccess, szData, charsmax(szData), szName, charsmax(szName), iCallBack );

	if ( equali( szData, MENU_REDISPLAY ) )
	{
		menu_display( iPlayer, iMenu );

		pokemod_funcend_debug( "MenuHandler MENU_REDISPLAY" );

		return PLUGIN_HANDLED;
	}

	menu_destroy( iMenu );

	if ( equal( szData, MENU_FAKE_EXIT ) )
	{
		MenuClose( iPlayer, iMenuType );

		pokemod_funcend_debug( "MenuHandler MENU_FAKE_EXIT" );

		return PLUGIN_HANDLED;
	}

	switch( iMenuType )
	{
		case MENU_SETUP:
		{
			if ( szData[0] == 'v' )
			{
				for ( new Int:i; i < PM_VERSION; i++ )
				{
					if ( equali( szData[1], szPokeModVersion[i] ) )
					{
						PlayerSetInfo( iPlayer, PINFO_VERSION, i );
						break;
					}
				}
				player_set_data( iPlayer, "PokeMod", "Version", szData[1] );
				MenuClose( iPlayer, iMenuType );
			}
			else
			{
				if ( szData[0] == 'd' )
				{
					if ( contain( szData, "done" ) != -1 )
					{
						PlayerSetInfo( iPlayer, PINFO_SETTING_DHUD, 0 );
						player_set_num( iPlayer, "PokeMod", "DHudPosX", PlayerGetInfo( iPlayer, PINFO_DHUDPOS_X ) );
						player_set_num( iPlayer, "PokeMod", "DHudPosY", PlayerGetInfo( iPlayer, PINFO_DHUDPOS_Y ) );

						MenuClose( iPlayer, iMenuType );
					}
					else
					{
						if ( contain( szData, "leftside" ) != -1 )
							PlayerSetInfo( iPlayer, PINFO_DHUDPOS_X, 13 );
						else if ( contain( szData, "rightside" ) != -1 )
							PlayerSetInfo( iPlayer, PINFO_DHUDPOS_X, -33 );
						else if ( contain( szData, "center" ) != -1 )
							PlayerSetInfo( iPlayer, PINFO_DHUDPOS_X, -100 );

						else if ( contain( szData, "up" ) != -1 )
							PlayerAddInfo( iPlayer, PINFO_DHUDPOS_Y, -1 );
						else if ( contain( szData, "down" ) != -1 )
							PlayerAddInfo( iPlayer, PINFO_DHUDPOS_Y, 1 );

						else if ( contain( szData, "left" ) != -1 )
							PlayerAddInfo( iPlayer, PINFO_DHUDPOS_X, -1 );
						else if ( contain( szData, "right" ) != -1 )
							PlayerAddInfo( iPlayer, PINFO_DHUDPOS_X, 1 );

						SetupShowDHUD( iPlayer );
						SetupDHUD( iPlayer );
					}
				}
				else if ( equal( szData, "color", 5 ) )
				{
					new Int:colorNum = str_to_num( szData[ 5 ] );
					PlayerSetInfo( iPlayer, PINFO_HUD_COLOR, colorNum );
					player_set_num( iPlayer, "PokeMod", "HudColor", colorNum );

					MenuClose( iPlayer, iMenuType );
				}
				else if ( equal( szData, "autocatch", 9 ) )
				{
					new Int:iAutoCatch = str_to_num( szData[ 9 ] );
					new Int:iOldAutoCatch = PlayerGetInfo( iPlayer, PINFO_SETTING_AUTOCATCH );
					if ( iAutoCatch != iOldAutoCatch )
					{
						PlayerSetInfo( iPlayer, PINFO_SETTING_AUTOCATCH, iAutoCatch );
						player_set_num( iPlayer, "PokeMod", "AutoBall", iAutoCatch );
					}

					SetupHowCatch( iPlayer );
				}
				else if ( equal( szData, "showdamage", 10 ) )
				{
					new Int:iValue = str_to_num( szData[ 10 ] );
					new Int:iOldValue = PlayerGetInfo( iPlayer, PINFO_SETTING_SHOWDAMAGE );
					if ( iValue != iOldValue )
					{
						PlayerSetInfo( iPlayer, PINFO_SETTING_SHOWDAMAGE, iValue );
						player_set_num( iPlayer, "PokeMod", "ShowSkillDamage", iValue );
					}

					MenuClose( iPlayer, iMenuType );
				}
				else if ( equal( szData, "showxpnum", 9 ) )
				{
					new Int:iValue = str_to_num( szData[ 9 ] );
					new Int:iOldValue = PlayerGetInfo( iPlayer, PINFO_SETTING_XPNUM );
					if ( iValue != iOldValue )
					{
						PlayerSetInfo( iPlayer, PINFO_SETTING_XPNUM, iValue );
						player_set_num( iPlayer, "PokeMod", "ShowXPNum", iValue );
					}

					MenuClose( iPlayer, iMenuType );
				}

				else
				{
					if ( contain( szData, "done" ) != -1 )
					{
						PlayerSetInfo( iPlayer, PINFO_SETTING_HUD, 0 );
						player_set_num( iPlayer, "PokeMod", "HudPos", PlayerGetInfo( iPlayer, PINFO_HUDPOS ) );

						MenuClose( iPlayer, iMenuType );
					}
					else
					{
						if ( contain( szData, "up" ) != -1 )
							PlayerAddInfo( iPlayer, PINFO_HUDPOS, -1 );
						else if ( contain( szData, "down" ) != -1 )
							PlayerAddInfo( iPlayer, PINFO_HUDPOS, 1 );

						SetupShowHUD( iPlayer );
						SetupHUD( iPlayer );
					}
				}
			}
		}
		case MENU_MAIN:
		{
			if ( equal( szData, "menu", 4 ) )
			{
				if ( equali( szData[ 4 ], "Setup", 5 ) )
				{
					if ( equali( szData[ 9 ], "HUD" ) )
					{
						SetupHUD( iPlayer );
					}
					else if ( equali( szData[ 9 ], "DHUD" ) )
					{
						SetupDHUD( iPlayer );
					}
					else if ( equali( szData[ 9 ], "Color" ) )
					{
						new Int:iColorNum = PlayerGetInfo( iPlayer, PINFO_HUD_COLOR );
						new Int:iMenu = MenuCreate( "Select a HUD Color" );
						new String:szColorNum[ 16 ];
						for ( new Int:i; i < HUD_COLOR; i++ )
						{
							formatex( szColorNum, charsmax(szColorNum), "color%d", i );
							if ( iColorNum == i )
								MenuAddItem( iMenu, szColorNum, "\r%s", szHudColors[ i ] );
							else
								MenuAddItem( iMenu, szColorNum, szHudColors[ i ] );
						}
						MenuExit( iPlayer, iMenu, .bExitOption = true );
						MenuDisplay( iPlayer, iMenu, MENU_SETUP );
					}
					else if ( equali( szData[ 9 ], "Ball" ) )
					{
						SetupAutoCatch( iPlayer );
					}
					else if ( equali( szData[ 9 ], "ShowDamage" ) )
					{
						SetupShowDamage( iPlayer );
					}
					else if ( equali( szData[ 9 ], "XPNum" ) )
					{
						SetupShowXPNum( iPlayer );
					}
					else
					{
						new Int:iMenu = MenuCreate( "Player Settings" );
						MenuAddItem( iMenu, "menuSetupBall", "Pokeball Use" );
						MenuAddItem( iMenu, "menuSetupHUD", "Info HUD Location" );
						MenuAddItem( iMenu, "menuSetupDHUD", "Event Locations" );
						MenuAddItem( iMenu, "menuSetupColor", "HUD Color" );
						MenuAddItem( iMenu, "menuSetupShowDamage", "Skill Damage Messages" );
						MenuAddItem( iMenu, "menuSetupXPNum", "HUD Exp Type" );
						MenuAddItem( iMenu, "ShowMenu(Main)", "Exit" );
						MenuExit( iPlayer, iMenu, .bExitOption = false );
						MenuDisplay( iPlayer, iMenu, MENU_MAIN );
					}
				}
				else if ( equali( szData[ 4 ], "BackPack" ) )
				{
					MenuBackPack( iPlayer );
				}
				else if ( equali( szData[ 4 ], "Server" ) )
				{
					new Int:iMenu = MenuCreate( "Server Information", g_szVersion );

					MenuAddItem( iMenu, "menuAbout", "About PokeMod" );
					MenuAddItem( iMenu, "menuPlayerPoke", "Players' Pokemon" );
					MenuAddItem( iMenu, "menuPokemon", "%d Pokemon", ArraySize( g_iPokemonNames ) - 1 );
					MenuAddItem( iMenu, "menuItems", "%d Items", ArraySize( g_iItemNames ) );
					MenuAddItem( iMenu, "menuLocations", "%d Locations", ArraySize( g_iLocationNames ) );
					MenuAddItem( iMenu, "menuSkills", "%d Skills", ArraySize( g_iSkillNames ) );

					MenuExit( iPlayer, iMenu, .bExitOption = true );
					MenuDisplay( iPlayer, iMenu, MENU_MAIN );
				}
				else if ( equali( szData[ 4 ], "About" ) )
				{
					SetupAbout( iPlayer );
					SetupInfo( iPlayer );
				}
				else if ( equali( szData[ 4 ], "PlayerPoke" ) )
				{
					CommandPlayerMenu( iPlayer, "say /playerpoke", .bAllowSelf = true, .bAllowMultiple = true, .bAdminCmd = false );
				}
				else if ( equali( szData[ 4 ], "Pokemon" ) )
				{
					CommandPokeMenu( iPlayer, "say /pokedex", .bOnlyOwned = false );
				}
				else if ( equali( szData[ 4 ], "Items" ) )
				{
					CommandItemMenu( iPlayer, "say /iteminfo", .bOnlyOwned = false );
				}
				else if ( equali( szData[ 4 ], "Locations" ) )
				{
					CommandLocationMenu( iPlayer, "say /map" );
				}
				else if ( equali( szData[ 4 ], "Skills" ) )
				{
					CommandSkillMenu( iPlayer, "say /skilldex", .bOnlyOwned = false );
				}
				else if ( equali( szData[ 4 ], "Admin" ) )
				{
					AdminMenu( iPlayer );
				}
				else if ( equali( szData[ 4 ], "Location" ) )
				{
					LocationMenu( iPlayer );
				}
				else if ( equali( szData[ 4 ], "Encounter" ) )
				{
					EncounterMenu( iPlayer );
				}
			}
			else
			{
				ScriptDoLine( iPlayer, szData );
			}
		}
		case MENU_PC, MENU_PC_ADVANCED:
		{
			if ( equal( szData, "box", 3 ) )
			{
				if ( szData[ 3 ] != EOS )
				{
					new Int:iBox = str_to_num( szData[ 3 ] );
					PlayerSetInfo( iPlayer, PINFO_PC_BOX, iBox );
					MenuPC( iPlayer );
				}
				else
				{
					new Int:iMenu = MenuCreate( "Select a Box" );

					new Int:iActiveBox = PlayerGetInfo( iPlayer, PINFO_PC_BOX );
					new Int:cPrefix, String:szBox[ 32 ];
					for ( new Int:i; i < 20; i++ )
					{
						cPrefix = ( iActiveBox == i ) ? 'y' : 'w';
						formatex( szBox, charsmax(szBox), "box%d", i );
						MenuAddItem( iMenu, szBox, "\%cBox #%d", cPrefix, i+1 );
					}

					MenuExit( iPlayer, iMenu, .bExitOption = true );

					MenuDisplay( iPlayer, iMenu, MENU_PC_ADVANCED );
				}
			}
			else if ( equal( szData, "send", 4 ) )
			{
				if ( szData[ 4 ] != EOS )
				{
					new Int:iSend = str_to_num( szData[ 4 ] );
					new Int:iActiveNum = PlayerGetInfo( iPlayer, PINFO_ACTIVE_POKENUM );

					if ( iSend == iActiveNum )
					{
						DHudEventMessage( iPlayer, "You cannot send your active pokemon to the PC." );
					}
					else
					{
						new String:szPlayerFile[ 64 ], String:szPokeSlot[ 32 ];
						nfv_player_file( iPlayer, szPlayerFile, charsmax( szPlayerFile ) );

						new Int:iBox = PlayerGetInfo( iPlayer, PINFO_PC_BOX );
						new Int:iBoxSlot = -1;

						for ( new Int:iPokeNum; iPokeNum < POKEMON_PER_BOX; iPokeNum++ )
						{
							SaveNameBoxSlot( szPokeSlot, charsmax(szPokeSlot), iBox, iPokeNum );
							if ( !nfv_get_data( szPlayerFile, szPokeSlot, "Name" ) )
							{
								iBoxSlot = iPokeNum;
								break;
							}
						}
						if ( iBoxSlot != -1 )
						{
							DHudEventMessage( iPlayer, "You sent %s to the PC", PokeNumToName( iSend, .playerID = iPlayer ) );
							PokemonSwitch( iPlayer, iSend, szPokeSlot );
						}
						else
						{
							DHudEventMessage( iPlayer, "You have no room in PC Box %d", iBox + 1 );
						}
					}

					MenuPC( iPlayer );
				}
				else
				{
					new Int:iMenu = MenuCreate( "Send which Pokemon to Emp`?" );

					new Int:iActiveNum = PlayerGetInfo( iPlayer, PINFO_ACTIVE_POKENUM );
					new Int:cPrefix;
					for ( new Int:iPokeNum; iPokeNum < POKEMON_PER_PLAYER; iPokeNum++ )
					{
						cPrefix = ( iActiveNum == iPokeNum ) ? 'r' : 'w';
						formatex( szData, charsmax(szData), "send%d", iPokeNum );
						MenuAddItem( iMenu, szData, "\%c%s", cPrefix, PokeNumToName( iPokeNum, .playerID = iPlayer ) );
					}

					MenuExit( iPlayer, iMenu, .bExitOption = true );

					MenuDisplay( iPlayer, iMenu, MENU_PC_ADVANCED );
				}
			}
			else if ( equal( szData, "retrieve", 8 ) )
			{
				if ( szData[ 8 ] != EOS )
				{
					new Int:iSlot = -1;
					for ( new Int:iPokeNum; iPokeNum < POKEMON_PER_PLAYER; iPokeNum++ )
					{
						if ( g_iPlayerPokemonStats[ iPlayer ][ iPokeNum ][ POKESTAT_POKEMON ] <= 0 )
						{
							iSlot = iPokeNum;
							break;
						}
					}

					if ( iSlot == -1 )
					{
						DHudEventMessage( iPlayer, "You have no room to take out a pokemon" );
					}
					else
					{
						new Int:iRetrieve = str_to_num( szData[ 8 ] );

						new String:szPlayerFile[ 64 ], String:szPokeSlot[ 32 ];
						nfv_player_file( iPlayer, szPlayerFile, charsmax( szPlayerFile ) );

						new Int:iBox = PlayerGetInfo( iPlayer, PINFO_PC_BOX );
						SaveNameBoxSlot( szPokeSlot, charsmax(szPokeSlot), iBox, iRetrieve );

						PokemonSwitch( iPlayer, iSlot, szPokeSlot );
						DHudEventMessage( iPlayer, "You retrieved %s from the PC", PokeNumToName( iSlot, .playerID = iPlayer ) );
					}

					MenuPC( iPlayer );
				}
				else
				{
					new Int:iSlot = -1;
					for ( new Int:iPokeNum; iPokeNum < POKEMON_PER_PLAYER; iPokeNum++ )
					{
						if ( g_iPlayerPokemonStats[ iPlayer ][ iPokeNum ][ POKESTAT_POKEMON ] <= 0 )
						{
							iSlot = iPokeNum;
							break;
						}
					}
					if ( iSlot == -1 )
					{
						DHudEventMessage( iPlayer, "You have no room to take out a pokemon" );
						MenuPC( iPlayer );
					}
					else
					{
						new Int:iMenu = MenuCreate( "Retrieve which Pokemon from Emp`?" );

						new String:szPlayerFile[ 64 ], String:szPokeSlot[ 32 ];
						nfv_player_file( iPlayer, szPlayerFile, charsmax( szPlayerFile ) );
						new Int:iBox = PlayerGetInfo( iPlayer, PINFO_PC_BOX );

						new String:szName[ NAME_LEN ];
						for ( new Int:iPokeNum; iPokeNum < POKEMON_PER_BOX; iPokeNum++ )
						{
							SaveNameBoxSlot( szPokeSlot, charsmax(szPokeSlot), iBox, iPokeNum );
							nfv_get_data( szPlayerFile, szPokeSlot, "Name", szName, charsmax( szName ) );
							if ( szName[ 0 ] == EOS )
								continue;

							formatex( szData, charsmax(szData), "retrieve%d", iPokeNum );
							MenuAddItem( iMenu, szData, szName );
						}

						MenuExit( iPlayer, iMenu, .bExitOption = true );

						MenuDisplay( iPlayer, iMenu, MENU_PC_ADVANCED );
					}
				}
			}
			else if ( equal( szData, "release", 7 ) )
			{
				if ( szData[ 7 ] == EOS )
				{
					new Int:iMenu = MenuCreate( "Release which Pokemon to the wild?" );

					new Int:iActiveNum = PlayerGetInfo( iPlayer, PINFO_ACTIVE_POKENUM );
					new Int:cPrefix;
					for ( new Int:iPokeNum; iPokeNum < POKEMON_PER_PLAYER; iPokeNum++ )
					{
						if ( g_iPlayerPokemonStats[ iPlayer ][ iPokeNum ][ POKESTAT_POKEMON ] <= 0 )
							continue;
						cPrefix = ( iActiveNum == iPokeNum ) ? 'r' : 'w';
						formatex( szData, charsmax(szData), "release%d", iPokeNum );
						MenuAddItem( iMenu, szData, "\%c%s", cPrefix, PokeNumToName( iPokeNum, .playerID = iPlayer ) );
					}

					MenuExit( iPlayer, iMenu, .bExitOption = true );

					MenuDisplay( iPlayer, iMenu, MENU_PC_ADVANCED );
				}
				else
				{
					new String:szPokeNum[ 8 ], String:szFinal[ 8 ];
					parse( szData[ 7 ], szPokeNum, charsmax(szPokeNum), szFinal, charsmax(szFinal) );
					new Int:iPokeNum = str_to_num( szPokeNum );
					new Int:iFinal = str_to_num( szFinal );

					if ( iFinal )
					{
						PlayerRelease( iPlayer, iPokeNum );
					}
					else
					{
						new String:szName[ NAME_LEN ];
						PokeNumToName( iPokeNum, szName, charsmax(szName), .playerID = iPlayer );
						new Int:iMenu = MenuCreate( "Select %s again to release", szName );

						new Int:iPokeID = g_iPlayerPokemonStats[ iPlayer ][ iPokeNum ][ POKESTAT_POKEMON ];

						//Create an array with random pokemon
						new Int:iPokemon[ 8 ];
						new Int:iPokeCreated = ArraySize( g_iPokemonNames );
						for ( new Int:i; i < sizeof iPokemon; i++ )
						{
							do iPokemon[ i ] = random( iPokeCreated );
							while ( iPokemon[ i ] == iPokeID );
						}

						//Place the releasing pokemon in the array randomly
						iPokemon[ random( sizeof iPokemon ) ] = iPokeID;

						for ( new Int:i; i < sizeof iPokemon; i++ )
						{
							if ( iPokemon[ i ] == iPokeID )
							{
								PokeNumToName( iPokeNum, szName, charsmax(szName), .playerID = iPlayer );
								formatex( szData, charsmax(szData), "release%d 1", iPokeNum );
							}
							else
							{
								PokeToName( iPokemon[ i ], szName, charsmax(szName) );
								formatex( szData, charsmax(szData), "release%d", iPokeNum );
							}
							MenuAddItem( iMenu, szData, "\w%s", szName );
						}

						MenuExit( iPlayer, iMenu, .bExitOption = true );

						MenuDisplay( iPlayer, iMenu, MENU_PC_ADVANCED );
					}
				}
			}
			else if ( equal( szData, "trade" ) )
			{
				TradeClear( iPlayer );
				TradeMenu( iPlayer );
			}
			else if ( equal( szData, "itemsend", 8 ) )
			{
				new String:szSendItemID[ 16 ], String:szAmount[ 16 ];
				parse( szData[8], szSendItemID, charsmax(szSendItemID), szAmount, charsmax(szAmount) );
				new Int:iSendItemID = str_to_num( szSendItemID );
				new Int:iAmount = str_to_num( szAmount );

				if ( iSendItemID > -1 )
				{
					if ( iAmount > 0 )
					{
						new String:szPlayerFile[ 64 ];
						nfv_player_file( iPlayer, szPlayerFile, charsmax( szPlayerFile ) );

						new String:szItemName[ NAME_LEN ];
						ItemToName( iSendItemID, szItemName, charsmax(szItemName) );
						nfv_add_num( szPlayerFile, "ItemStorage", szItemName, iAmount );
						PlayerGiveItem( iPlayer, iSendItemID, -iAmount );

						DHudEventMessage( iPlayer, "You sent %d %s to Emp`", iAmount, szItemName );

						MenuPC( iPlayer );
					}
					else
					{
						new String:szItemName[ NAME_LEN ];
						ItemToName( iSendItemID, szItemName, charsmax(szItemName) );

						new Int:iMenu = MenuCreate( "How many %s would you like to send?", szItemName );

						new Int:iItemMax;
						PlayerHasItem( iPlayer, iSendItemID, iItemMax );

						new const String:szSendDataFormat[] = "itemsend %d %d";
						new const String:szSendNameFormat[] = "%d";

						formatex( szData, charsmax(szData), szSendDataFormat, iSendItemID, iItemMax );
						MenuAddItem( iMenu, szData, szSendNameFormat, iItemMax );

						for ( iAmount = ReduceNumber( iItemMax ); iAmount >= 1; iAmount /= 10 )
						{
							formatex( szData, charsmax(szData), szSendDataFormat, iSendItemID, iAmount );
							MenuAddItem( iMenu, szData, szSendNameFormat, iAmount );
						}

						MenuExit( iPlayer, iMenu, .bExitOption = true );

						MenuDisplay( iPlayer, iMenu, MENU_PC_ADVANCED );
					}
				}
				else
				{
					new Int:iMenu = MenuCreate( "Send which Item to Emp`?" );

					new Array:iPlayerItems = g_iPlayerItems[ iPlayer ];
					new Int:iSize = ArraySize( iPlayerItems ) / _:PLAYER_ITEM;
					if ( iSize )
					{
						new Int:iMenu = MenuCreate( "PokeItems" );

						for ( new Int:iItemID, Int:iItemAmount, Int:iItemNum, Int:iProp;
							iItemNum < iSize;
							iItemNum++
						){
							iItemID = ArrayGetCell( iPlayerItems, ( ( iItemNum * _:PLAYER_ITEM ) + _:ITEM_ID ) );

							iProp = ArrayGetCell( g_iItemProps, iItemID );
							if ( iProp & ( 1 << _:ITEM_HIDDEN ) )
								continue;

							iItemAmount = ArrayGetCell( iPlayerItems, ( ( iItemNum * _:PLAYER_ITEM ) + _:ITEM_AMOUNT ) );

							formatex( szData, charsmax(szData), "itemsend %d", iItemID );
							MenuAddItem( iMenu, szData, "%s ( %d )", ItemToName( iItemID ), iItemAmount );
						}
					}

					if ( menu_items( iMenu ) <= 0 )
					{
						MenuAddItem( iMenu, szData, "You cannot send any items to your storage." );
					}

					MenuExit( iPlayer, iMenu, .bExitOption = true );

					MenuDisplay( iPlayer, iMenu, MENU_PC_ADVANCED );
				}
			}
			else if ( equal( szData, "itemretrieve", 12 ) )
			{
				new String:szRetrieveItemID[ 16 ], String:szAmount[ 16 ];
				parse( szData[12], szRetrieveItemID, charsmax(szRetrieveItemID), szAmount, charsmax(szAmount) );
				new Int:iRetrieveItemID = str_to_num( szRetrieveItemID );
				new Int:iAmount = str_to_num( szAmount );

				new String:szPlayerFile[ 64 ];
				nfv_player_file( iPlayer, szPlayerFile, charsmax( szPlayerFile ) );

				if ( iRetrieveItemID > -1 )
				{
					new String:szItemName[ NAME_LEN ];
					ItemToName( iRetrieveItemID, szItemName, charsmax(szItemName) );

					new Int:iItemMax = nfv_get_num( szPlayerFile, "ItemStorage", szItemName );

					if ( iAmount > 0 && iAmount <= iItemMax )
					{
						PlayerGiveItem( iPlayer, iRetrieveItemID, iAmount );
						nfv_set_num( szPlayerFile, "ItemStorage", szItemName, iItemMax - iAmount );

						DHudEventMessage( iPlayer, "You retrieved %d %s from Emp`", iAmount, szItemName );

						MenuPC( iPlayer );
					}
					else
					{
						new Int:iMenu = MenuCreate( "How many %s would you like to retrieve?", szItemName );

						new const String:szRetrieveDataFormat[] = "itemretrieve %d %d";
						new const String:szRetrieveNameFormat[] = "%d";

						formatex( szData, charsmax(szData), szRetrieveDataFormat, iRetrieveItemID, iItemMax );
						MenuAddItem( iMenu, szData, szRetrieveNameFormat, iItemMax );

						for ( iAmount = ReduceNumber( iItemMax ); iAmount >= 1; iAmount /= 10 )
						{
							formatex( szData, charsmax(szData), szRetrieveDataFormat, iRetrieveItemID, iAmount );
							MenuAddItem( iMenu, szData, szRetrieveNameFormat, iAmount );
						}

						MenuExit( iPlayer, iMenu, .bExitOption = true );

						MenuDisplay( iPlayer, iMenu, MENU_PC_ADVANCED );
					}
				}
				else
				{
					new Int:iMenu = MenuCreate( "Retrieve which Item from Emp`?" );

					new Int:iItemID, String:szItemName[ NAME_LEN ];
					new Int:iNameLine, Int:iProp, Int:iAmount;
					while ( nfv_get_linedata( szPlayerFile, "ItemStorage", NFV_WILDCARD, szData, charsmax( szData ),
							.name_line_start = ( iNameLine + 1 ), .name_line_find = iNameLine,
							.name_copy = szItemName, .name_len = charsmax( szItemName )
							)
					){
						if ( ( iAmount = str_to_num( szData ) ) )
						{
							iItemID = NameToItem( szName );

							iProp = ArrayGetCell( g_iItemProps, iItemID );
							if ( iProp & ( 1 << _:ITEM_HIDDEN ) )
								continue;

							formatex( szData, charsmax(szData), "itemretrieve %d", iItemID );
							MenuAddItem( iMenu, szData, "%s ( %d )", ItemToName( iItemID ), iAmount );
						}
					}

					if ( menu_items( iMenu ) <= 0 )
					{
						MenuAddItem( iMenu, szData, "There are no items in your storage." );
					}

					MenuExit( iPlayer, iMenu, .bExitOption = true );

					MenuDisplay( iPlayer, iMenu, MENU_PC_ADVANCED );
				}
			}
		}
		case MENU_BACKPACK:
		{
			if ( equal( szData, "pokes", 5 ) )
			{
				new Int:iPokeID = str_to_num( szData[5] );
				if ( !iPokeID )
				{
					new Int:iMenu = MenuCreate( "Your Pokemon" );
					new Int:iActiveNum = PlayerGetInfo( iPlayer, PINFO_ACTIVE_POKENUM );
					for ( new Int:iPokeNum; iPokeNum < POKEMON_PER_PLAYER; iPokeNum++ )
					{
						iPokeID = g_iPlayerPokemonStats[ iPlayer ][ iPokeNum ][ POKESTAT_POKEMON ];
						if ( iPokeID <= 0 )
							continue;

						formatex( szName, charsmax(szName), "\%c%s\RLvl: %d", ( iActiveNum == iPokeNum ) ? 'y' : 'w', PokeNumToName( iPokeNum, .playerID = iPlayer ), g_iPlayerPokemonStats[ iPlayer ][ iPokeNum ][ POKESTAT_LEVEL ] );
						formatex( szData, charsmax(szData), "pokes%d", iPokeID );

						MenuAddItem( iMenu, szData, szName );
					}

					MenuAddItem( iMenu, "pokes-1", "\rChange Active Pokemon" );

					MenuExit( iPlayer, iMenu, .bExitOption = true );
					MenuDisplay( iPlayer, iMenu, MENU_BACKPACK );
				}
				else if ( iPokeID == -1 )
				{
					MenuChangePokemon( iPlayer );
				}
				else
				{
					for ( new Int:iPokeNum; iPokeNum < POKEMON_PER_PLAYER; iPokeNum++ )
					{
						if ( iPokeID == g_iPlayerPokemonStats[ iPlayer ][ iPokeNum ][ POKESTAT_POKEMON ] )
						{
							PokemonShowInfo( .iViewer = iPlayer, .iOwner = iPlayer, .iPokeNum = iPokeNum );
						}
					}
				}
			}
			else if ( equal( szData, "items", 5 ) )
			{
				ItemMenu( iPlayer );
			}
			else if ( equal( szData, "map", 3 ) )
			{
				PlayerViewMap( iPlayer );
			}
			else if ( equal( szData, "artitem", 7 ) )
			{
				new Int:iItemID = str_to_num( szData[7] );
				ItemUse( iPlayer, iItemID );
			}
			else if ( equal( szData, "artifact", 8 ) )
			{
				new String:szPlayerFile[ 64 ];
				nfv_player_file( iPlayer, szPlayerFile, charsmax( szPlayerFile ) );
				new Int:nameLine, Int:iArtifacts;

				new Int:iMenu = MenuCreate( "Artifacts" );

				new Array:iPlayerItems = g_iPlayerItems[ iPlayer ];
				new Int:iSize = ArraySize( iPlayerItems ) / _:PLAYER_ITEM;
				if ( iSize )
				{
					for ( new Int:iItemID, Int:iItemNum, Int:iProp, Int:iAmount;
						iItemNum < iSize;
						iItemNum++
					){
						iItemID = ArrayGetCell( iPlayerItems, ( ( iItemNum * _:PLAYER_ITEM ) + _:ITEM_ID ) );

						iProp = ArrayGetCell( g_iItemProps, iItemID );
						if ( iProp & ( 1 << _:ITEM_HIDDEN ) )
							continue;
						if ( !( iProp & ( 1 << _:ITEM_ARTIFACT ) ) )
							continue;

						if ( iProp & ( 1 << _:ITEM_NO_USE ) )
							copy( szData, charsmax(szData), MENU_REDISPLAY );
						else
							formatex( szData, charsmax(szData), "artitem%d", iItemID );

						iAmount = ArrayGetCell( iPlayerItems, ( ( iItemNum * _:PLAYER_ITEM ) + _:ITEM_AMOUNT ) );

						MenuAddItem( iMenu, szData, "%s (%d) - %s", ItemToName( iItemID ), iAmount, ItemInfo( iItemID, "ItemInfo" ) );
						iArtifacts++;
					}
				}

				while ( nfv_get_linedata( szPlayerFile, "PokeModSpecial", NFV_WILDCARD, szData, charsmax( szData ),
						.name_line_start = ( nameLine + 1 ), .name_line_find = nameLine,
						.name_copy = szName, .name_len = charsmax( szName )
						)
				){
					trim( szName );
					if ( szName[0] == EOS || szName[0] == '_' )
						continue;

					MenuAddItem( iMenu, MENU_REDISPLAY, szName );
					iArtifacts++;
				}

				if ( !iArtifacts )
					MenuAddItem( iMenu, MENU_REDISPLAY, "You have no artifacts!" );

				MenuExit( iPlayer, iMenu, .bExitOption = true );
				MenuDisplay( iPlayer, iMenu, MENU_BACKPACK );
			}
		}
		case MENU_CHANGE_POKE:
		{
			new Int:iPokeNum = str_to_num( szData );
			if ( iPokeNum != -1 )
			{
				PlayerChangePokemon( iPlayer, iPokeNum, .bForced = false );
			}
			else
			{
				SetupHowCatch( iPlayer );
			}
		}
		case MENU_ENCOUNTER:
		{
			if ( equal( szData, "pokedex" ) )
			{
				new Int:iEncounterProps = PlayerGetInfo( iPlayer, PINFO_ENCOUNTER_PROPS );

				if ( iEncounterProps & ENCPROP_GHOST )
				{
					DHudEventMessage( iPlayer, "Pokedex could not identify the Ghost" );
				}
				else
				{
					new Int:iEncounterID = PlayerGetInfo( iPlayer, PINFO_ENCOUNTER_POKEMON );
					PlayerPokedex( iPlayer, iEncounterID );
				}
			}
			else if ( equal( szData, "poke" ) )
			{
				MenuChangePokemon( iPlayer );
			}
			else if ( equal( szData, "item" ) )
			{
				ItemMenu( iPlayer );
			}
			else if ( equal( szData, "run" ) )
			{
				EncounterRun( iPlayer );
			}
			else if ( equal( szData, "catch", 5 ) )
			{
				new Int:iEncounterID = PlayerGetInfo( iPlayer, PINFO_ENCOUNTER_POKEMON );
				new Int:iEncounterHP = PlayerGetInfo( iPlayer, PINFO_ENCOUNTER_HP );
				new Int:iEncounterLevel = PlayerGetInfo( iPlayer, PINFO_ENCOUNTER_LEVEL );
				new Int:iEncounterIVs = PlayerGetInfo( iPlayer, PINFO_ENCOUNTER_IVS );
				new Int:iEncounterMaxHP = PokemonMaxHP( iEncounterID, iEncounterLevel, iEncounterIVs );
				new Int:iItemID = str_to_num( szData[ 5 ] );

				EncounterAttemptCatch( iPlayer, iEncounterID, iEncounterHP, iEncounterMaxHP, iItemID );
			}
		}
		case MENU_EVOLVE:
		{
			new String:szPokeNum[ 8 ], String:szEvolveID[ 8 ];
			new Int:iPokeNum, Int:iEvolveID;
			parse( szData, szPokeNum, charsmax(szPokeNum), szEvolveID, charsmax(szEvolveID) );
			iPokeNum = str_to_num( szPokeNum );
			iEvolveID = str_to_num( szEvolveID );

			new String:szPokeName[ NAME_LEN ], String:szEvolveName[ NAME_LEN ];
			PokeNumToName( iPokeNum, szPokeName, charsmax(szPokeName), .playerID = iPlayer );
			PokeToName( iEvolveID, szEvolveName, charsmax(szEvolveName) );

			DHudEventMessage( iPlayer, "%s evolved into %s!", szPokeName, szEvolveName );

			//Get the save slot
			new String:szSaveName[ NAME_LEN ];
			SaveNameSlot( szSaveName, charsmax(szSaveName), iPokeNum );

			//If it's the default name, update the name to the evolve name
			new Int:iPokeID = g_iPlayerPokemonStats[ iPlayer ][ iPokeNum ][ POKESTAT_POKEMON ];
			if ( equali( szPokeName, PokeToName( iPokeID ) ) )
			{
				copy( g_szPlayerPokemonNames[ iPlayer ][ iPokeNum ], charsmax( g_szPlayerPokemonNames[][] ), szEvolveName );

				player_set_data( iPlayer, szSaveName, "Name", szEvolveName );
			}

			//Update the pokemon to the evolved pokemon
			g_iPlayerPokemonStats[ iPlayer ][ iPokeNum ][ POKESTAT_POKEMON ] = iEvolveID;
			player_set_data( iPlayer, szSaveName, gPokeStatNames[ POKESTAT_POKEMON ], PokeToName( iEvolveID ) );
		}
		case MENU_USE_ITEM:
		{
			switch( szData[0] )
			{
				case 'u':
				{
					new Int:iItemID = str_to_num( szData[1] );
					ItemUse( iPlayer, iItemID );
					if ( PlayerGetInfo( iPlayer, PINFO_POKEITEM_DOWN ) )
						ItemMenu( iPlayer );
				}
				case 'g':
				{
					new String:szItemID[ 8 ], String:szPokeNum[ 8 ], String:szExtraScript[ 128 ];
					parse( szData[1], szItemID, charsmax(szItemID), szPokeNum, charsmax(szPokeNum), szExtraScript, charsmax(szExtraScript) );

					new Int:iItemID = str_to_num( szItemID );
					new Int:iPokeNum = str_to_num( szPokeNum );

					//if they exited
					if ( iPokeNum == -1 )
					{
						//give the item back
						PlayerGiveItem( iPlayer, iItemID, 1 );
					}
					else
					{
						//give the item to the pokemon
						PokemonGiveItem( iPlayer, iPokeNum, iItemID, szExtraScript );
					}

					MenuClose( iPlayer, iMenuType );
				}
			}
		}
		case MENU_SKILLS:
		{
			new Int:iSkillNum = str_to_num( szData );
			PlayerSetInfo( iPlayer, PINFO_ACTIVE_SKILLNUM, iSkillNum );
			SkillMenu( iPlayer );
		}
		case MENU_LEARN_SKILL:
		{
			new String:szPokeNum[ 16 ], String:szSkillID[ 16 ], String:szSkillNum[ 16 ];
			parse( szData, szPokeNum, charsmax(szPokeNum), szSkillID, charsmax(szSkillID), szSkillNum, charsmax(szSkillNum) );

			new Int:iPokeNum = str_to_num( szPokeNum );
			new POKESKILL:iSkillID = POKESKILL:str_to_num( szSkillID );
			new Int:iSkillNum = str_to_num( szSkillNum );

			if ( iSkillNum == -1 )
			{
				new Int:iMenu = MenuCreate( "Select a skill to replace with %s", SkillToName( iSkillID ) );

				new POKESKILL:tempSkillID;
				for ( new Int:tempSkillNum; tempSkillNum < SKILLS_PER_POKEMON; tempSkillNum++ )
				{
					formatex( szData, charsmax(szData), "%d %d %d", iPokeNum, iSkillID, tempSkillNum );
					tempSkillID = g_iPlayerPokemonSkills[ iPlayer ][ iPokeNum ][ tempSkillNum ];
					MenuAddItem( iMenu, szData, "Replace %s", SkillToName( tempSkillID ) );
				}

				MenuAddItem( iMenu, MENU_FAKE_EXIT, "\rBlock Skill" );

				MenuExit( iPlayer, iMenu, .bExitOption = false );
				MenuDisplay( iPlayer, iMenu, MENU_LEARN_SKILL );
			}
			else
			{
				new POKESKILL:iOldSkillID = g_iPlayerPokemonSkills[ iPlayer ][ iPokeNum ][ iSkillNum ];
				g_iPlayerPokemonSkills[ iPlayer ][ iPokeNum ][ iSkillNum ] = iSkillID;
				g_iPlayerSkillPP[ iPlayer ][ iPokeNum ][ iSkillNum ] = SkillInfo( iSkillID, SI_PP );
				SavePlayerPokeSkill( iPlayer, iPokeNum, iSkillNum );

				DHudEventMessage( iPlayer, "%s forgot %s and learned skill %s.", PokeNumToName( iPokeNum, .playerID = iPlayer ), SkillToName( iOldSkillID ), SkillToName( iSkillID ) );
			}
		}
		case MENU_COMMAND, MENU_ADMINCOMMAND:
		{
			client_cmd( iPlayer, szData );
		}
		case MENU_TRADE, MENU_TRADE_SUB:
		{
			new bool:bShowTrade = true;
			new Int:iTradePlayer = PlayerGetInfo( iPlayer, PINFO_TRADE_PLAYER );

			if ( equal( szData, "accept" ) )
			{
				if ( PlayerGetInfo( iTradePlayer, PINFO_TRADE_PLAYER ) != iPlayer )
				{
					//Other player is not trading with you
					client_print( iPlayer, print_chat, "DEBUG: %s is not trading with you", PlayerToName( iTradePlayer ) );
				}
				else if ( PlayerGetInfo( iTradePlayer, PINFO_TRADE_ACCEPT ) )
				{
					//Finish trade, both accepted
					TradeComplete( iPlayer, iTradePlayer );
					bShowTrade = false;
				}
				else if ( PlayerGetInfo( iPlayer, PINFO_TRADE_ACCEPT ) )
				{
					//Player wants to edit the trade
					PlayerSetInfo( iPlayer, PINFO_TRADE_ACCEPT, 0 );
					client_print( iPlayer, print_chat, "DEBUG: %s is editing the trade", PlayerToName( iPlayer ) );
				}
				else
				{
					//Show a player accepted the trade
					PlayerSetInfo( iPlayer, PINFO_TRADE_ACCEPT, 1 );
					client_print( iPlayer, print_chat, "DEBUG: %s accepted the trade", PlayerToName( iPlayer ) );
				}
			}

			else
			{
				if ( PlayerGetInfo( iPlayer, PINFO_TRADE_ACCEPT ) || PlayerGetInfo( iTradePlayer, PINFO_TRADE_ACCEPT ) )
				{
					//A player accepted the trade, don't allow other player to edit values
					client_print( iPlayer, print_chat, "DEBUG: Cannot edit trade after a player accepts" );
				}
				else if ( equal( szData, "player", 6 ) )
				{
					iTradePlayer = str_to_num( szData[6] );
					if ( iTradePlayer )
					{
						PlayerSetInfo( iPlayer, PINFO_TRADE_PLAYER, iTradePlayer );
						if ( PlayerGetInfo( iTradePlayer, PINFO_TRADE_PLAYER ) == iPlayer )
						{
							//Players are now trading with eachother
							client_print( iPlayer, print_chat, "DEBUG: Trading with %s started", PlayerToName( iTradePlayer ) );
							client_print( iTradePlayer, print_chat, "DEBUG: Trading with %s started", PlayerToName( iPlayer ) );
						}
						else
						{
							//Other player needs to start trading
							TradeMenu( iPlayer );
							client_print( iTradePlayer, print_chat, "DEBUG: %s wants to trade. say /trade", PlayerToName( iPlayer ) );
							bShowTrade = false;
						}
					}
					else
					{
						TradePlayer( iPlayer );
						bShowTrade = false;
					}
				}
				else if ( equal( szData, "poke", 4 ) )
				{
					if ( szData[4] )
					{
						new Int:iActiveNum = PlayerGetInfo( iPlayer, PINFO_ACTIVE_POKENUM );
						new Int:iPokemon = str_to_num( szData[4] );
						new Int:iPokeNum = PlayerPokemonNum( iPlayer, iPokemon );
						if ( iPokeNum > -1 && iPokeNum != iActiveNum )
						{
							PlayerSetInfo( iPlayer, PINFO_TRADE_POKEMON, iPokemon );
							new Int:iLevel = g_iPlayerPokemonStats[ iPlayer ][ iPokeNum ][ POKESTAT_LEVEL ];
							PlayerSetInfo( iPlayer, PINFO_TRADE_LEVEL, iLevel );
						}
						else
						{
							PlayerSetInfo( iPlayer, PINFO_TRADE_POKEMON, 0 );
							PlayerSetInfo( iPlayer, PINFO_TRADE_LEVEL, 0 );
						}
					}
					TradePokemon( iPlayer );
					bShowTrade = false;
				}
				else if ( equal( szData, "item", 4 ) )
				{
					if ( szData[4] )
					{
						new Int:iItemID = str_to_num( szData[4] );
						if ( iItemID == -1 || PlayerHasItem( iPlayer, iItemID ) != -1 )
						{
							PlayerSetInfo( iPlayer, PINFO_TRADE_ITEM, iItemID );
							PlayerSetInfo( iPlayer, PINFO_TRADE_ITEMNUM, 1 );
						}
					}
					TradeItem( iPlayer );
					bShowTrade = false;
				}
				else if ( equal( szData, "inum", 4 ) )
				{
					if ( szData[4] )
					{
						new Int:iTradeAmount = str_to_num( szData[4] );
						new Int:iItemAmount;
						PlayerHasItem( iPlayer, PlayerGetInfo( iPlayer, PINFO_TRADE_ITEM ), iItemAmount )
						if ( iItemAmount >= iTradeAmount )
							PlayerSetInfo( iPlayer, PINFO_TRADE_ITEMNUM, iTradeAmount );
					}
					TradeItemAmount( iPlayer );
					bShowTrade = false;
				}
				else if ( equal( szData, "money", 5 ) )
				{
					if ( szData[5] )
					{
						new Int:iMoney = str_to_num( szData[5] );
						if ( PlayerGetMoney( iPlayer ) >= iMoney )
							PlayerSetInfo( iPlayer, PINFO_TRADE_MONEY, iMoney );
					}
					TradeMoney( iPlayer );
					bShowTrade = false;
				}
			}

			if ( bShowTrade )
			{
				TradeMenu( iPlayer );
				TradeMenu( iTradePlayer );
			}
		}
	}

	pokemod_funcend_debug( "MenuHandler" );

	return PLUGIN_HANDLED;
}

PM_FUNC_NORM_ATTRIB MenuMain( Int:iPlayer, bool:bForceDisplay )
{
	if ( !is_user_connected( iPlayer ) )
		return;

	pokemod_funcstart_debug( "MenuMain" );

	new Int:iMenu = MenuCreate( "PokeMod %s", g_szVersion );

	new Int:iEncounterID = PlayerGetInfo( iPlayer, PINFO_ENCOUNTER_POKEMON );
	if ( iEncounterID > 0 )
	{
		new String:szEncounterName[ NAME_LEN ];
		if ( PlayerGetInfo( iPlayer, PINFO_ENCOUNTER_PROPS ) & ENCPROP_GHOST )
			copy( szEncounterName, charsmax(szEncounterName), "\dGhost" );
		else
			PokeToName( iEncounterID, szEncounterName, charsmax(szEncounterName) );

		MenuAddItem( iMenu, "menuEncounter", "\yFighting: %s", szEncounterName );
	}

	new Int:iLocation = PlayerGetInfo( iPlayer, PINFO_LOCATION );
	new String:szLocation[ NAME_LEN ];
	LocationToName( iLocation, szLocation, charsmax(szLocation) );

	if ( g_iPlayerPokemonStats[ iPlayer ][ 0 ][ POKESTAT_POKEMON ] > 0 )
	{
		if ( PlayerGetInfo( iPlayer, PINFO_TRAVELING ) )
		{
			MenuAddItem( iMenu, "menuLocation", "Traveling To: %s", LocationToName( PlayerGetInfo( iPlayer, PINFO_TRAVEL_TO ) ) );
		}
		else
		{
			MenuAddItem( iMenu, "menuLocation", "Location: %s", szLocation );
		}
	}

	g_iScriptMenu = iMenu;
	LocationScript( iPlayer, iLocation, "MainMenu", "" );
	g_iScriptMenu = -1;

	MenuAddItem( iMenu, "menuBackPack", "Your Back Pack" );

	if ( !PlayerGetInfo( iPlayer, PINFO_BOT ) )
	{
		MenuAddItem( iMenu, "menuSetup", "Settings" );

		if ( is_user_admin( iPlayer ) )
			MenuAddItem( iMenu, "menuAdmin", "Admin Menu" );

		MenuAddItem( iMenu, "menuServer", "About Server" );
	}

	MenuExit( iPlayer, iMenu, .bExitOption = true );

	if ( bForceDisplay )
	{
		menu_cancel( iPlayer );
		g_iPlayerMenuType[ iPlayer ] = MENU_MAIN;
		menu_display( iPlayer, iMenu );
	}
	else
		MenuDisplay( iPlayer, iMenu, MENU_MAIN );

	pokemod_funcend_debug( "MenuMain" );
}

PM_FUNC_NORM_ATTRIB MenuChangePokemon( Int:iPlayer )
{
	pokemod_funcstart_debug( "MenuChangePokemon" );

	new Int:iMenu = MenuCreate( "Change Pokemon" );

	new Int:iActiveNum = PlayerGetInfo( iPlayer, PINFO_ACTIVE_POKENUM );
	new Int:cPrefix;

	new Int:iPokes;
	new Int:iPokeID, Int:iPokeIVs, Int:iPokeEV;
	new Int:iLevel, Int:iHP, Int:iMaxHP, String:szHP[ 32 ];
	for ( new Int:iPokeNum, String:szPokeNum[ 8 ]; iPokeNum < POKEMON_PER_PLAYER; iPokeNum++ )
	{
		iPokeID = g_iPlayerPokemonStats[ iPlayer ][ iPokeNum ][ POKESTAT_POKEMON ];
		if ( iPokeID <= 0 )
			continue;

		cPrefix = ( iActiveNum == iPokeNum ) ? 'y' : 'w';

		iLevel = g_iPlayerPokemonStats[ iPlayer ][ iPokeNum ][ POKESTAT_LEVEL ];
		iHP = g_iPlayerPokemonStats[ iPlayer ][ iPokeNum ][ POKESTAT_HP ];

		if ( iHP <= 0 )
		{
			cPrefix = 'd';
			copy( szHP, charsmax(szHP), "Fainted" );
		}
		else
		{
			iPokeIVs = g_iPlayerPokemonStats[ iPlayer ][ iPokeNum ][ POKESTAT_IVS ];
			iPokeEV = g_iPlayerPokemonStats[ iPlayer ][ iPokeNum ][ POKESTAT_HP_EV ];

			iMaxHP = PokemonMaxHP( iPokeID, iLevel, iPokeIVs, iPokeEV );

			formatex( szHP, charsmax(szHP), "HP:%d/%d", iHP, iMaxHP );
		}

		formatex( szPokeNum, charsmax(szPokeNum), "%d", iPokeNum );
		MenuAddItem( iMenu, szPokeNum, "\%c%32s Lvl:%d %s", cPrefix, PokeNumToName( iPokeNum, .playerID = iPlayer ), iLevel, szHP );

		iPokes++;
	}

	if ( iPokes < POKEMON_PER_PLAYER )
	{
		MenuAddItem( iMenu, "-1", "\rHow to catch Pokemon" );
	}

	MenuExit( iPlayer, iMenu, .bExitOption = true );

	MenuDisplay( iPlayer, iMenu, MENU_CHANGE_POKE );

	pokemod_funcend_debug( "MenuChangePokemon" );
}

PM_FUNC_NORM_ATTRIB MenuBackPack( Int:iPlayer )
{
	pokemod_funcstart_debug( "MenuBackPack" );

	new Int:iMenu = MenuCreate( "Back Pack" );

	MenuAddItem( iMenu, "pokes", "Pokemon" );
	MenuAddItem( iMenu, "items", "Items" );
	MenuAddItem( iMenu, "map", "Map" );
	MenuAddItem( iMenu, "artifact", "Artifacts" );

	MenuExit( iPlayer, iMenu, .bExitOption = true );

	MenuDisplay( iPlayer, iMenu, MENU_BACKPACK );

	pokemod_funcend_debug( "MenuBackPack" );
}

PM_FUNC_NORM_ATTRIB MenuPC( Int:iPlayer )
{
	pokemod_funcstart_debug( "MenuPC" );

	new Int:iMenu = MenuCreate( "Emp`s PC" );

	MenuAddItem( iMenu, "box", "Box #%d", PlayerGetInfo( iPlayer, PINFO_PC_BOX ) + 1 );
	MenuAddItem( iMenu, "send", "Send Pokemon" );
	MenuAddItem( iMenu, "retrieve", "Retrieve Pokemon" );
	MenuAddItem( iMenu, "release", "Release Pokemon" );
	MenuAddItem( iMenu, "trade", "Trade Pokemon" );
	MenuAddItem( iMenu, "itemsend", "Send Item" );
	MenuAddItem( iMenu, "itemretrieve", "Retrieve Item" );

	MenuExit( iPlayer, iMenu, .bExitOption = true );

	MenuDisplay( iPlayer, iMenu, MENU_PC );

	pokemod_funcend_debug( "MenuPC" );
}

PM_FUNC_NORM_ATTRIB MenuFilter( Int:iPlayer, String:szFilter[], PM_MENUS:iMenuType )
{
	if ( szFilter[ 0 ] == EOS )
		return 0;

	new Int:iOldMenu, Int:iTrash;
	player_menu_info( iPlayer, iTrash, iOldMenu );
	if ( iOldMenu == -1 )
		return 0;

	new Int:iOldItems = menu_items( iOldMenu );
	if ( iOldItems <= 1 )
		return 0;

	pokemod_funcstart_debug( "MenuFilter" );

	new Int:iAccess, String:szData[ 128 ], String:szName[ 64 ], Int:iCallback;

	//Here we are going to loop through all items to see what is common between the items
	//That way if we filter 'po' and the command is 'pm_givepoke', it won't show all the items
	new Int:iDataStart;
	new String:szTempData[ 128 ], Int:iDataLen;

	menu_item_getinfo( iOldMenu, 0, iAccess, szData, charsmax(szData), _, _, iCallback );
	menu_item_getinfo( iOldMenu, iOldItems - 1, iAccess, szTempData, charsmax(szTempData), _, _, iCallback );
	strtolower( szData );
	strtolower( szTempData );

	iDataLen = strlen( szTempData );
	for ( new Int:iChar = 0; iChar < iDataLen; iChar++ )
	{
		if ( szData[ iChar ] != szTempData[ iChar ] )
		{
			iDataStart = iChar;
			//We found what was different, let's break the loop
			break;
		}
	}

	new Int:iFilterMenu = MenuCreate( "Command Filter '%s'", szFilter );

	for ( new Int:iItemNum; iItemNum < iOldItems; iItemNum++ )
	{
		menu_item_getinfo( iOldMenu, iItemNum, iAccess, szData, charsmax(szData), szName, charsmax(szName), iCallback );

		if ( !equal( szData, MENU_FAKE_EXIT ) )
		{
			copyc( szTempData, charsmax(szTempData), szData[ iDataStart ], ';' );

			if ( containi( szTempData, szFilter ) != -1 || containi( szName, szFilter ) != -1 )
			{
				MenuAddItem( iFilterMenu, szData, szName );
			}
		}
	}

	new Int:iFilteredItems = menu_items( iFilterMenu );

	if ( iFilteredItems )
	{
		MenuExit( iPlayer, iFilterMenu, .bExitOption = true );

		MenuDisplay( iPlayer, iFilterMenu, iMenuType );
	}
	else
	{
		menu_destroy( iFilterMenu );
	}

	pokemod_funcend_debug( "MenuFilter %d Items Filtered", iFilteredItems );

	return iFilteredItems;
}




